package autokeyboard.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowStateListener;
import java.util.ArrayList;

import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu.Separator;
import javax.swing.JTable;
import javax.swing.UIManager;

import autokeyboard.data.RobotData;
import autokeyboard.handler.AutoKeyboardEvent;

import com.melloware.jintellitype.JIntellitype;

@SuppressWarnings("serial")
public class AutoKeyboard extends JFrame
{
	private TablePanel			tablePanel					= new TablePanel(this);
	private PanelButton			panelButton					= new PanelButton(this);

	private JMenuBar			menuBar						= new JMenuBar();

	private JMenu				menuFile					= new JMenu();
	private JMenuItem			menuItemNew					= new JMenuItem();
	private JMenuItem			menuItemSave				= new JMenuItem();
	private JMenuItem			menuItemSaveAs				= new JMenuItem();
	private JMenuItem			menuItemOpen				= new JMenuItem();
	private Separator			s1							= new Separator();
	private JMenuItem			menuItemExit				= new JMenuItem();

	private JMenu				menuSetting					= new JMenu();
	private Separator			s2							= new Separator();
	private JMenu				menuLAF						= new JMenu();
	private JMenuItem			menuItemControlKey			= new JMenuItem();
	private JCheckBoxMenuItem	cbMenuItemNimbus			= new JCheckBoxMenuItem();
	private JCheckBoxMenuItem	cbMenuItemWindows			= new JCheckBoxMenuItem();
	private JCheckBoxMenuItem	cbMenuItemMetal				= new JCheckBoxMenuItem();
	private JCheckBoxMenuItem	cbMenuItemWindowsClassic	= new JCheckBoxMenuItem();
	private ButtonGroup			group						= new ButtonGroup();

	private JMenu				menuHelp					= new JMenu();
	private JMenuItem			menuItemHelpTopic			= new JMenuItem();
	private Separator			s3							= new Separator();
	private JMenuItem			menuItemAbout				= new JMenuItem();

	private AutoKeyboardEvent	event						= new AutoKeyboardEvent(this);
	private RobotData			data						= new RobotData();

	private JTable				table						= new JTable();
	private ArrayList<Object[]>	listObject					= new ArrayList<Object[]>();

	public AutoKeyboard()
	{
		initComponent();
		setFrameProperties();

		panelButton.setTable(tablePanel.getTable());
		panelButton.setListObject(tablePanel.getListObject());
		panelButton.setListSelectionModel(tablePanel.getListSelectionModel());

		this.table = tablePanel.getTable();
		this.listObject = tablePanel.getListObject();

		tablePanel.setBtUp(panelButton.getBtUp());
		tablePanel.setBtDown(panelButton.getBtDown());
		tablePanel.setBtDelete(panelButton.getBtDelete());
	}

	private void initComponent()
	{
		setMainLayout();

		setMenuFileProperties();
		setMenuSettingProperties();
		setMenuHelpProperties();

		menuItemEvent();
		windowEvent();
	}

	private void setFrameProperties()
	{
		this.setTitle("Auto Keyboard");
		this.setIconImage(new ImageIcon(getClass().getResource("/Small_Icons/Icon.png")).getImage());
		this.setMinimumSize(new Dimension(840, 600));
		this.setSize(840, 600);
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		this.getContentPane().setBackground(new Color(232, 232, 232));
		// this.setResizable(false);
	}

	private void setMainLayout()
	{
		this.setJMenuBar(menuBar);
		this.setLayout(new BorderLayout());
		this.add(tablePanel, BorderLayout.CENTER);
		this.add(panelButton, BorderLayout.NORTH);

		Dimension d = this.getSize();
		panelButton.setPreferredSize(new Dimension(d.width, 75));
		tablePanel.setPreferredSize(new Dimension(d.width, d.height));

	}

	private void setMenuFileProperties()
	{
		menuFile.setFont(new Font("Calibri", 0, 15));
		menuFile.setText("File");
		menuFile.setMnemonic('F');
		menuBar.add(menuFile);

		menuItemNew.setText("New               ");
		menuItemNew.setMnemonic('N');
		menuItemNew.setFont(menuFile.getFont());
		menuItemNew.setIcon(new ImageIcon(getClass().getResource("/Small_Icons/btNew.png")));
		menuFile.add(menuItemNew);

		menuItemSave.setText("Save");
		menuItemSave.setMnemonic('S');
		menuItemSave.setFont(menuFile.getFont());
		menuItemSave.setIcon(new ImageIcon(getClass().getResource("/Small_Icons/btSave.png")));
		menuFile.add(menuItemSave);

		menuItemSaveAs.setText("Save As");
		menuItemSaveAs.setMnemonic('A');
		menuItemSaveAs.setFont(menuFile.getFont());
		menuItemSaveAs.setIcon(new ImageIcon(getClass().getResource("/Small_Icons/btSave.png")));
		menuFile.add(menuItemSaveAs);

		menuItemOpen.setText("Open");
		menuItemOpen.setMnemonic('O');
		menuItemOpen.setFont(menuFile.getFont());
		menuItemOpen.setIcon(new ImageIcon(getClass().getResource("/Small_Icons/btOpen.png")));
		menuFile.add(menuItemOpen);
		menuFile.add(s1);

		menuItemExit.setText("Exit");
		menuItemExit.setMnemonic('X');
		menuItemExit.setFont(menuFile.getFont());
		menuItemExit.setIcon(new ImageIcon(getClass().getResource("/Small_Icons/btExit.png")));
		menuFile.add(menuItemExit);
	}

	private void setMenuSettingProperties()
	{
		menuSetting.setFont(menuFile.getFont());
		menuSetting.setText("Setting");
		menuSetting.setMnemonic('S');
		menuBar.add(menuSetting);

		menuItemControlKey.setFont(menuFile.getFont());
		menuItemControlKey.setText("Controls");
		menuItemControlKey.setMnemonic('C');
		menuItemControlKey.setIcon(new ImageIcon(getClass().getResource("/Small_Icons/btSetting.png")));
		menuSetting.add(menuItemControlKey);
		menuSetting.add(s2);

		menuLAF.setFont(menuFile.getFont());
		menuLAF.setText("Change Theme");
		menuLAF.setIcon(new ImageIcon(getClass().getResource("/Small_Icons/btChangeTheme.png")));
		menuLAF.setMnemonic('T');
		menuSetting.add(menuLAF);

		group.add(cbMenuItemMetal);
		group.add(cbMenuItemNimbus);
		group.add(cbMenuItemWindows);
		group.add(cbMenuItemWindowsClassic);

		cbMenuItemNimbus.setSelected(true);

		cbMenuItemMetal.setFont(menuFile.getFont());
		cbMenuItemMetal.setText("Metal");
		cbMenuItemMetal.setMnemonic('M');
		menuLAF.add(cbMenuItemMetal);

		cbMenuItemNimbus.setFont(menuFile.getFont());
		cbMenuItemNimbus.setText("Nimbus");
		cbMenuItemNimbus.setMnemonic('N');
		menuLAF.add(cbMenuItemNimbus);

		cbMenuItemWindows.setFont(menuFile.getFont());
		cbMenuItemWindows.setText("Windows");
		cbMenuItemWindows.setMnemonic('W');
		menuLAF.add(cbMenuItemWindows);

		cbMenuItemWindowsClassic.setFont(menuFile.getFont());
		cbMenuItemWindowsClassic.setText("Windows Classic");
		cbMenuItemWindowsClassic.setMnemonic('I');
		menuLAF.add(cbMenuItemWindowsClassic);

	}

	private void setMenuHelpProperties()
	{
		menuHelp.setFont(menuFile.getFont());
		menuHelp.setText("Help");
		menuHelp.setMnemonic('H');
		menuBar.add(menuHelp);

		menuItemHelpTopic.setFont(menuFile.getFont());
		menuItemHelpTopic.setText("Help topics");
		menuItemHelpTopic.setMnemonic('H');
		menuItemHelpTopic.setIcon(new ImageIcon(getClass().getResource("/Small_Icons/btHelp.png")));
		menuHelp.add(menuItemHelpTopic);
		menuHelp.add(s3);

		menuItemAbout.setFont(menuFile.getFont());
		menuItemAbout.setText("About");
		menuItemAbout.setMnemonic('A');
		menuItemAbout.setIcon(new ImageIcon(getClass().getResource("/Small_Icons/btAbout.png")));
		menuHelp.add(menuItemAbout);
	}

	/**
	 * This method will set event for all menu item in main frame
	 */
	private void menuItemEvent()
	{
		fileMenuItemEvent();
		settingMenuItemEvent();
		helpMenuItemEvent();
	}

	/**
	 * add event to all menu item in file menu
	 */
	private void fileMenuItemEvent()
	{
		menuItemNew.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent e)
			{
				event.menuItemNewEvent(table, listObject);
			}
		});

		menuItemSave.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent e)
			{
				event.menuItemSaveEvent(table, listObject);
			}
		});

		menuItemSaveAs.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent e)
			{
				event.menuItemSaveAsEvent(table, listObject);
			}
		});

		menuItemOpen.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent e)
			{
				event.menuItemOpenEvent(table, listObject );
			}
		});

		menuItemExit.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent e)
			{
				event.menuItemExitEvent();
			}
		});

	}

	/**
	 * add event to all menu item in setting menu
	 */
	private void settingMenuItemEvent()
	{
		JCheckBoxMenuItem[] listCheckBox = { cbMenuItemMetal, cbMenuItemNimbus, cbMenuItemWindows, cbMenuItemWindowsClassic };

		for (final JCheckBoxMenuItem item : listCheckBox)
		{
			item.addActionListener(new ActionListener()
			{

				@Override
				public void actionPerformed(ActionEvent e)
				{
					if (item.isSelected())
					{
						event.setLookAndFeel(item.getText());
					}
				}
			});
		}
	}

	/**
	 * add event to all menu item in help menu
	 */
	private void helpMenuItemEvent()
	{
		menuItemHelpTopic.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent e)
			{
				event.menuItemHelpTopicEvent();
			}
		});

		menuItemAbout.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent e)
			{
				event.menuItemAboutEvent();
			}
		});
	}

	/**
	 * This will add WindowsStateListener for this class.
	 * <p>
	 * When this frame is change state from minimize to normal. It will
	 * unregister hot key
	 */
	private void windowEvent()
	{
		this.addWindowStateListener(new WindowStateListener()
		{

			@Override
			public void windowStateChanged(WindowEvent e)
			{
				if (getState() == JFrame.NORMAL && getState() != JFrame.MAXIMIZED_BOTH)
				{
					unregisterHotKey();
				}
			}
		});
		
		this.addWindowListener(new WindowAdapter()
		{
			@Override
			public void windowClosing(WindowEvent evt)
			{
				event.menuItemExitEvent();
			}
		});
	}

	/**
	 * This method will unregister your current hot key when you press any key
	 * in the table
	 */
	private void unregisterHotKey()
	{
		JIntellitype.getInstance().unregisterHotKey(data.keyRegister(StartOptionDialog.listHostKey[0]));
		JIntellitype.getInstance().unregisterHotKey(data.keyRegister(StartOptionDialog.listHostKey[1]));
		JIntellitype.getInstance().unregisterHotKey(data.keyRegister(StartOptionDialog.listHostKey[2]));
	}

	public static void main(String args[])
	{
		try
		{
			for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels())
			{
				if ("Nimbus".equals(info.getName()))
				{
					UIManager.setLookAndFeel(info.getClassName());
					break;
				}
			}
		} catch (Exception e)
		{
		}
		new AutoKeyboard().setVisible(true);
	}
}
